﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SMSConsulting.SMSLIB.Utilities;

namespace Access.PowerTools.AbstractionLayer
{
    public class AccessDatabaseObjectInfo
    {
        public AccessDatabaseObjectInfo(
            AccessDataBaseObjectTypeEnumeration type,
            string name)
        {
            Type = type;
            Name = name;
        }


        private const string _objectTypeAndNameSeparator = " - ";
        public AccessDatabaseObjectInfo(string objectTypeAndName)
        {
            int separatorPos = objectTypeAndName.IndexOf(_objectTypeAndNameSeparator);
            Type = (AccessDataBaseObjectTypeEnumeration)
                                                             Enum.Parse(typeof(AccessDataBaseObjectTypeEnumeration),
                                                                        objectTypeAndName.Substring(0, separatorPos).Trim());
            Name = objectTypeAndName.Substring(separatorPos + _objectTypeAndNameSeparator.Length).Trim();
        }
        public string ObjectTypeAndName
        {
            get
            {
                return Type.ToString() + _objectTypeAndNameSeparator + Name;
            }
        }

        public AccessDataBaseObjectTypeEnumeration Type { get; set; }
        public string Name { get; set; }
        public string BackUpFileName
        {
            get
            {
                return GetBackUpFileName(this.Type, this.Name);   
            }
        }

        public static string GetBackUpFileName(
               AccessDataBaseObjectTypeEnumeration objectType,
               string objectName)
        {
            string fileExt = (objectType == AccessDataBaseObjectTypeEnumeration.Table) ? ".xml" : ".txt";

            string fileName = getbackUpFileNameNoExt(objectType, objectName);

            return fileName + fileExt;
        }
        public static string GetBackUpFileNameForObjectSchema(
               AccessDataBaseObjectTypeEnumeration objectType,
               string objectName)
        {
            string fileExt = (objectType == AccessDataBaseObjectTypeEnumeration.Table) ? ".xml" : ".txt";

            string fileName = getbackUpFileNameNoExt(objectType, objectName) + "Schema";
            return fileName + fileExt;
        }
        public static string GetBackUpFileNameForDelimitedTextExport(
               AccessDataBaseObjectTypeEnumeration objectType,
               string objectName)
        {
            string fileExt = ".txt";

            string fileName = getbackUpFileNameNoExt(objectType, objectName);
            return fileName + "_TextData" + fileExt;
        }

        private static string getbackUpFileNameNoExt(
               AccessDataBaseObjectTypeEnumeration objectType,
               string objectName)
        {
            string prefix = "";

            switch (objectType)
            {
                case AccessDataBaseObjectTypeEnumeration.Table:
                    prefix = TABLE_FILE_PREFIX;break;
                case AccessDataBaseObjectTypeEnumeration.Query:
                    prefix = QUERY_FILE_PREFIX; break;
                case AccessDataBaseObjectTypeEnumeration.Form:
                    prefix = FORM_FILE_PREFIX; break;
                case AccessDataBaseObjectTypeEnumeration.Report:
                    prefix = REPORT_FILE_PREFIX; break;
                case AccessDataBaseObjectTypeEnumeration.Macro:
                    prefix = MACRO_FILE_PREFIX; break;
                case AccessDataBaseObjectTypeEnumeration.Module:
                    prefix = MODULE_FILE_PREFIX; break;
                default:
                    throw new ApplicationException(
                        string.Format("{0}.{1}: Undefined object type {2}",
                        System.Reflection.MethodInfo.GetCurrentMethod().ReflectedType.Name,
                        System.Reflection.MethodInfo.GetCurrentMethod().Name,
                        objectType));

            }

            string encodedObjectName = Access.PowerTools.Utilities.Strings.EncodeObjectName(objectName);

            return prefix + encodedObjectName;
        }

        private const string TABLE_FILE_PREFIX = "TABLE_";
        private const string QUERY_FILE_PREFIX = "QUERY_";
        private const string FORM_FILE_PREFIX = "FORM_";
        private const string REPORT_FILE_PREFIX = "REPORT_";
        private const string MACRO_FILE_PREFIX = "MACRO_";
        private const string MODULE_FILE_PREFIX = "MODULE_";

        public static AccessDataBaseObjectTypeEnumeration GetObjectTypeByFileName(string fileName)
        {
            SMSConsulting.SMSLIB.Utilities.RunTimeAssert.NotNullOrEmptyString(fileName);

            // it could be fullpath - let's cut folder path info
            fileName = System.IO.Path.GetFileName(fileName);  

            if (fileName.StartsWith(TABLE_FILE_PREFIX, StringComparison.InvariantCultureIgnoreCase))
                return AccessDataBaseObjectTypeEnumeration.Table;
            if (fileName.StartsWith(QUERY_FILE_PREFIX, StringComparison.InvariantCultureIgnoreCase))
                return AccessDataBaseObjectTypeEnumeration.Query;
            if (fileName.StartsWith(FORM_FILE_PREFIX, StringComparison.InvariantCultureIgnoreCase))
                return AccessDataBaseObjectTypeEnumeration.Form;
            if (fileName.StartsWith(REPORT_FILE_PREFIX, StringComparison.InvariantCultureIgnoreCase))
                return AccessDataBaseObjectTypeEnumeration.Report;
            if (fileName.StartsWith(MACRO_FILE_PREFIX, StringComparison.InvariantCultureIgnoreCase))
                return AccessDataBaseObjectTypeEnumeration.Macro;
            if (fileName.StartsWith(MODULE_FILE_PREFIX, StringComparison.InvariantCultureIgnoreCase))
                return AccessDataBaseObjectTypeEnumeration.Module;

            throw new ApplicationException(
                string.Format("{0}.{1}: Can't get object type from file Name {2}",
                System.Reflection.MethodInfo.GetCurrentMethod().ReflectedType.Name,
                System.Reflection.MethodInfo.GetCurrentMethod().Name,
                fileName));
        }

        private static bool isKnownFileExt(string fileExt)
        {
            if (string.Compare(fileExt, ".txt", true) == 0) return true;
            if (string.Compare(fileExt, ".xml", true) == 0) return true;
            return false;
        }

        public static string GetObjectNameFromFileName(string fileName)
        {
            SMSConsulting.SMSLIB.Utilities.RunTimeAssert.NotNullOrEmptyString(fileName);

            // it could be fullpath - let's cut folder path info
            fileName = System.IO.Path.GetFileName(fileName);  
            
            // we assume that object file name consists of
            // a [prefixWithUnderScore][objectName][.3charsFileExt] 

            int pointPos = fileName.LastIndexOf(".");  
            RunTimeAssert.True(pointPos > 0, "Can't find object filename extension"); 

            RunTimeAssert.True(isKnownFileExt(fileName.Substring(fileName.Length - 4)), "Unefined file extension");      

            fileName = fileName.Substring(0, fileName.Length - 4); // cut file extension
            int undescorePos = fileName.IndexOf("_");
            
            RunTimeAssert.True(undescorePos > 0, "Can't find object filename prefix"); 

            return fileName.Substring(undescorePos+1);
        }

        public string SimulationSeedObjectInfoFileFullPath
        {
            get
            {
                string fileName =
                    Access.PowerTools.Settings.Globals.NorthdwindDatabaseSeedFilesFolder +
                    AccessDatabaseObjectInfo.GetBackUpFileName(this.Type , this.Name);
                return fileName;
            }
        }
        public string SimulationSeedObjectSchemaFileFullPath
        {
            get
            {
                string fileName =
                    Access.PowerTools.Settings.Globals.NorthdwindDatabaseSeedFilesFolder +
                    AccessDatabaseObjectInfo.GetBackUpFileName(this.Type, this.Name);
                return fileName;
            }
        }


    }
}
